/*
  (C) 2007 - Boston University
  Contact: Michael Ocean 

	this file was adapted from a CS511 submission

  This work is a part of the larger snBench project.  Information
  can be found at: http://csr.bu.edu/snbench 

  This program is free software; you can redistribute it and/or
  modify it under the terms of Version 2 of the GNU General Public 
  License.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package stepide;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;

import java.awt.event.ActionEvent;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.print.PrinterJob;
import java.awt.Component;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JScrollPane;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JFileChooser;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import step.DuplicateID;
import step.Graph;
import step.ValueNode;
import stepide.STEPVisualizer.JStepPanel;
import stepide.STEPVisualizer.JStepPanelEventListener;
import stepide.STEPVisualizer.JStepPanel.FakeStepNode;
import stepide.NodeOption;
import stepide.ValueOption;
import step.parse.Parser;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class IDEStarter extends javax.swing.JFrame implements JStepPanelEventListener, MenuFactoryListener {
	private static final long serialVersionUID = -8512235648221674832L;
	private JSplitPane jPane;
	private JSplitPane jRightPane;
	private JTabbedPane jTabbedPane;
	private JScrollPane jEditorScrollPane;	
	private JEditorPane jEditorPane;
	private JFileChooser fileChooser;

	private StatusBar status = new StatusBar();
	
	private final int DEFAULT_PALETTE_WIDTH = 150;
	private final int DEFAULT_JPANE_WIDTH = 1000;
	private final int DEFAULT_JPANE_HEIGHT = 750;
	
	private int newTabCount = 0;

	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		IDEStarter inst = new IDEStarter();
		inst.setVisible(true);
	}

	
	SplashScreen splash = new SplashScreen();
	
	public IDEStarter() {
		super();

		splash.showSplash();
		
		initGUI();
	}
	
	private void initGUI() {
		try {
			splash.update(20);
			
			this.setTitle("STEP IDE");
			this.setIconImage(new ImageIcon("stepide/icons/ide.png").getImage());
			this.getContentPane().add(new ToolBarFactory(this), BorderLayout.NORTH);
			this.add(status, java.awt.BorderLayout.SOUTH);
						
			splash.update(40);		    	

			fileChooser = new JFileChooser("./");
			fileChooser.setMultiSelectionEnabled(true);

			try {
				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		    	} catch (Exception e) {
	    	}

			splash.update(60);		    	
		    /*
			jptpanel = new JPanel();
			jptpanel.setLayout(new BorderLayout());
			jptpanel.add(new JLabel("Object to insert"),BorderLayout.NORTH);
			
	        jTreePane = new JScrollPane();

	        DefaultMutableTreeNode top =
	            new DefaultMutableTreeNode("STEP");
	        createNodes(top);
	        jTree = new JTree(top);			        
	        jTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
			jTreePane.setViewportView(jTree);
			jTree.addTreeSelectionListener(new TreeSelectionListener() {
				public void valueChanged(TreeSelectionEvent evt) {
					jTreeValueChanged(evt);
				}
			});
			
			jptpanel.add(jTreePane,BorderLayout.CENTER);
			*/
			_nodeSelector = new NodeSelector(null);

		    	
			jTabbedPane = new JTabbedPane();
			jTabbedPane.addChangeListener(new ChangeListener(){

				public void stateChanged(ChangeEvent e) {
					resetArrowMode();
					
					if(jTabbedPane.getTabCount()>1)
						refreshXML();
				}
				
			});
			splash.update(80);
			
			newTab(null);

			jEditorScrollPane = new JScrollPane();

			jEditorPane = new JEditorPane();
			jEditorScrollPane.setViewportView(jEditorPane);
			jEditorPane.setText(curSTEPGraph().getXml());

			jRightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, jTabbedPane, jEditorScrollPane);
			//jPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jptpanel, jRightPane);
		    jPane = jRightPane;
			jPane.setPreferredSize(new Dimension(DEFAULT_JPANE_WIDTH, DEFAULT_JPANE_HEIGHT));
			jRightPane.setPreferredSize(new Dimension(DEFAULT_JPANE_WIDTH, DEFAULT_JPANE_HEIGHT));


			jTabbedPane.setPreferredSize(
					new Dimension((int)jPane.getPreferredSize().getWidth()-DEFAULT_PALETTE_WIDTH, 
							(int)jPane.getPreferredSize().getHeight()/2));
			/*
			jTree.setSize(new Dimension(DEFAULT_PALETTE_WIDTH,
					(int)jPane.getPreferredSize().getHeight()));
			*/
			
			jPane.setBorder(new EmptyBorder(3,3,3,3));
			
			getContentPane().add(jPane, BorderLayout.CENTER);				
			
			
			this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			splash.update(90);
			setJMenuBar(new MenuFactory(this));
			pack();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		splash.update(100);
		splash.dispose();
	}
	
	public void newTab(Graph g)
	{	
		//JScrollPane jCurGraph = new JScrollPane();
		
		/* MJO - big changes start here ... */
		// STEPGraph sg = new STEPGraph(this);

		if(g == null)
			g = Graph.newEmptyGraph();
		JStepPanel jsp = new JStepPanel(g);
		jsp.setVisible(true);
		jsp.addStepPanelEventListener(this);
		
		//jCurGraph.setViewportView(jsp);	
		//jCurGraph.setSize(jTabbedPane.getWidth(), jTabbedPane.getHeight());
		jsp.setSize(jTabbedPane.getWidth(), jTabbedPane.getHeight());
		//jsp.setSize(jCurGraph.getWidth(), jCurGraph.getHeight());
		jTabbedPane.add(jsp, "Untitled" + newTabCount++);
		jTabbedPane.setSelectedComponent(jsp);
	}
	
	/*
	public JScrollPane curTabPane()
	{
		return (JScrollPane)(jTabbedPane.getSelectedComponent());
	}
	*/
	
	public JStepPanel curSTEPGraph()
	{
		return (JStepPanel)jTabbedPane.getSelectedComponent();
		//curTabPane().getViewport().getView();
	}
			
	private String SelectedJTreeOperation = null;
	
	/*
	private void jTreeValueChanged(TreeSelectionEvent evt) 
	{
		DefaultMutableTreeNode n = (DefaultMutableTreeNode)
								jTree.getSelectionPath().getPath()
								[jTree.getSelectionPath().getPath().length-1];
	
		Object s = n.getUserObject();
		Object[] temp = n.getUserObjectPath();
		if(temp.length==0)
			return;
		if(((String)temp[1]).compareTo("opcode")==0)
		{
			for(int i = temp.length-2; i>=2; i--)
				s=(Object)((String)temp[i]+"."+(String)s);
		}	
		
		SelectedJTreeOperation = (String)s;
		
	}//+n.getUserObject()
	*/
	
	public void message(Component comp, String str) 
	{
		JOptionPane.showMessageDialog(comp, str);
	}		
	
	public void refreshXML() 
	{
		jEditorPane.setText(curSTEPGraph().getXml());
		repaint();
	}

	public void CanvasDoubleClicked(int x, int y) {
		//if(jTree.getSelectionCount()!=1)
		//	return;
		 
		if (SelectedJTreeOperation == null)
			return;

		if(SelectedJTreeOperation.equals("ARROW"))
			return;
		
		//step.Node n = NodeCreator(SelectedJTreeOperation);
		step.Node n = InvokeNodeCreationDialog();
		
		if(n!=null){
			try{
				curSTEPGraph().addStepNode(n);
			}catch(DuplicateID ex){
				JOptionPane.showMessageDialog(this, "The node you attempted to add has the same ID of an existing node.","Node could not be added",JOptionPane.ERROR_MESSAGE);
			}
			refreshXML();
		}
	}

	public void CanvasLeftClicked(int x, int y) {
		resetArrowMode();
	}

	public class NodeContextMenu extends JPopupMenu{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JMenuItem delete;
		private JMenuItem properties;
		private FakeStepNode node;
		private int x;
		private int y;
		
		public void setEvent(FakeStepNode n, int X, int Y){
			node = n;
			x = X;
			y = Y;
		}
		
		public NodeContextMenu()
		{
			super();			
			properties = new JMenuItem("Properties");
			delete = new JMenuItem("Delete");
			
			properties.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {
				NodeDoubleClicked(node, x, y);
			}});
			
			delete.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {
				curSTEPGraph().removeStepNode(node.getNode());
				refreshXML();
			}});
			
			add(delete);
			add(properties);
		}
	}

	public class EdgeContextMenu extends JPopupMenu{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JMenuItem delete;
		private FakeStepNode nodeSource;
		private FakeStepNode nodeTarget;
		
		public void setEvent(FakeStepNode nSource, FakeStepNode nTarget){
			nodeSource = nSource;
			nodeTarget = nTarget;
		}
		
		public EdgeContextMenu()
		{
			super();			
			delete = new JMenuItem("Delete");
			
			delete.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {
				curSTEPGraph().removeStepEdge(nodeSource.getNode(),nodeTarget.getNode());
				refreshXML();
			}});
			
			add(delete);
		}
	}
	
	public class CanvasContextMenu extends JPopupMenu{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JMenuItem create;
		private JMenuItem options;
		private JMenuItem close;
		
		public CanvasContextMenu()
		{
			super();
			create = new JMenuItem("Create Node");
			options = new JMenuItem("Graph Properties");
			close = new JMenuItem("Close Tab");
			
			create.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {
				CanvasDoubleClicked(0,0);
			}});

			options.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					String s = JOptionPane.showInputDialog(
											"Specify the Graph ID",
											curSTEPGraph().getGraphID());
					if(s==null)
						return;
					curSTEPGraph().setGraphID(s);
					refreshXML();
				}
			});

			
			close.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {
				doActionFileClose(e);
			}});
			
			add(create);
			add(options);
			add(close);
		}
	}
	
	private CanvasContextMenu CanvasPopup;
	private NodeContextMenu NodePopup;
	private EdgeContextMenu EdgePopup;
	
	public void CanvasRightClicked(int x, int y) {
		if (CanvasPopup == null) {
			CanvasPopup = new CanvasContextMenu();
		}

		if (CanvasPopup.isVisible())
			CanvasPopup.setVisible(false);
		else {
			CanvasPopup.setVisible(true);
			CanvasPopup.show(curSTEPGraph(), x,y);
		}
	}

	public void NodeDoubleClicked(FakeStepNode node, int x, int y) {
		System.out.println("Intercepted NodeDoubleclicked");
		if(node.getNode() instanceof ValueNode){
			ValueOption dialog = new ValueOption(this, node.getNode());
			dialog.setVisible(true);
		} else {
			NodeOption dialog = new NodeOption(this, node.getNode());
			dialog.setVisible(true);
		}

	}

	protected step.Node nodeFrom = null;
	
	protected boolean shown = false;
	
	public void NodeLeftClicked(FakeStepNode node, int x, int y) {
		 
		if (SelectedJTreeOperation == null)
			return;

		if(!SelectedJTreeOperation.equals("ARROW"))
			return;
		

		if(nodeFrom == null){
			nodeFrom = node.getNode();
			
			if(!shown){
				JOptionPane.showMessageDialog(this,"You have just selected a parent node.\n\nIf you select another node that node will become the child of this node.\nTo abort click anywhere in the graph that is not a node.\n\nThe status bar tells you which end of the arrow you are selecting.\n(this message will not be displayed again)","About Arrows",JOptionPane.INFORMATION_MESSAGE);
				shown = true;
			}
			
			status.alterDefaultMessage(StatusBar.DEFAULT_MSG_ARROW_END);
			return;
		}

		curSTEPGraph().addEdge(nodeFrom,node.getNode());
			
		resetArrowMode();
		refreshXML();
		
		status.alterDefaultMessage(StatusBar.DEFAULT_MSG_ARROW_BEGIN);
	}

	public void NodeRightClicked(FakeStepNode node, int x, int y) {
		if (NodePopup == null) {
			NodePopup = new NodeContextMenu();
		}
		NodePopup.setEvent(node, x,y);
		
		if (NodePopup.isVisible())
			NodePopup.setVisible(false);
		else {
			NodePopup.setVisible(true);
			
			NodePopup.show(curSTEPGraph(), x,y);
		}	}	
	

	NodeSelector _nodeSelector = null;
	private step.Node InvokeNodeCreationDialog(){		
		_nodeSelector.updateAvailableItems(curSTEPGraph());
		_nodeSelector.setVisible(true);		
		step.Node node = null;
		
		node = _nodeSelector.getUserSelectedNode();
		_nodeSelector.resetUserSelection();
		
		

		return node;
	}
	
	public void doActionBindToSxe(ActionEvent evt) {
		// DOME: something like this
		/*
		StepGraph g = graphMap.get(getSelectedTab());
		if(g.isUpdated()) {
			status.setMessage("Graph must be saved to do binding!", StatusBar.MSG_WARNING);
			doActionFileSave(evt);
		}
		*/
		
		fileChooser.setFileFilter(new StepFileFilter(StepFileFilter.FORMAT_XML));
		fileChooser.setMultiSelectionEnabled(false);
		int returnVal = fileChooser.showOpenDialog(this);
		fileChooser.setMultiSelectionEnabled(true);
				
        if(returnVal == JFileChooser.APPROVE_OPTION) {
    		File file = fileChooser.getSelectedFile();
    		
			String sxeLoc = JOptionPane.showInputDialog("What is the URL of SXE to use?", "http://sxe.bu.edu:8080");
			while(sxeLoc != null && sxeLoc.length() < 1) {
				sxeLoc = JOptionPane.showInputDialog("What is the URL of SXE to use?", "http://sxe.bu.edu:8080");
			}
			if(sxeLoc != null) { // null returned if user clicks cancel
				
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				PrintStream st = new PrintStream(baos);
				sxe.Poster.poster(sxeLoc, file, st);
				JOptionPane.showMessageDialog(this, baos.toString(),"Result of post",JOptionPane.INFORMATION_MESSAGE);
			}
			status.setMessage("Sent XML graph to specified SXE", StatusBar.MSG_OK);
			
        }
	}

	public void doActionEditRedo(ActionEvent evt) {
		JOptionPane.showMessageDialog(this, "Redo functionality to be implemented in future versions.");
	}
	
	public void doActionEditRemoveSelection(ActionEvent evt) {
		curSTEPGraph().removeSelected();
		refreshXML();
	}

	public void doActionEditUndo(ActionEvent evt) {
		JOptionPane.showMessageDialog(this, "Undo functionality to be implemented in future versions.");		
	}

	public void doActionFileClose(ActionEvent evt) {
		jTabbedPane.remove(jTabbedPane.getSelectedComponent());		
		refreshXML();
	}

	public void doActionFileNew(ActionEvent evt) {
		newTab(null);
		repaint();
	}
	
	public void doActionFileOpen(ActionEvent evt) {
		status.setMessage("Loading file...", StatusBar.MSG_OK);

		fileChooser.setFileFilter(new StepFileFilter(StepFileFilter.FORMAT_XML));
		int returnVal = fileChooser.showOpenDialog(this);

		StringBuffer sFailedFiles = new StringBuffer();
		
        if(returnVal == JFileChooser.APPROVE_OPTION) {
        	File[] file = fileChooser.getSelectedFiles();
        	this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        	for(int i = 0; i<file.length; i++)
        	{
        		step.Graph stepg = Parser.Parse(file[i],false);
        		if(stepg!=null){
        			newTab(stepg);

        			jTabbedPane.setTitleAt(jTabbedPane.getSelectedIndex(), 
        				file[i].getName());
        			jEditorPane.setText(curSTEPGraph().getXml());
        		}
        		else
        			sFailedFiles.append(file[i] + "\n");

        	}
        	if(sFailedFiles.length()>0){
        		JOptionPane.showMessageDialog(this, "Some of the files you attempted to open could not be opened.\n\nPerhaps they are not valid STEP XML files?\n\n" + sFailedFiles.toString());	
        	}
        	this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
		status.setDefaultMessage();
        repaint();
	}
	
	public void doActionFilePrint(ActionEvent evt) {
		PrinterJob printJob = PrinterJob.getPrinterJob();
		printJob.setPrintable(curSTEPGraph().getPrintable());
		if (printJob.printDialog()) {
			try {
				printJob.print();
			}
			catch (java.awt.print.PrinterException ex) {
				ErrorManager.LogError(ex);
			}
		}
	}

	public void doActionFileSave(ActionEvent evt) {
        refreshXML();
        status.setMessage("Saving file...", StatusBar.MSG_OK);
        
        fileChooser.setFileFilter(new StepFileFilter(StepFileFilter.FORMAT_XML));
		int returnVal = fileChooser.showSaveDialog(this);

        if(returnVal == JFileChooser.APPROVE_OPTION) {
        	File file = fileChooser.getSelectedFile();

        	
    		BufferedOutputStream bos;
			try {
				bos = new BufferedOutputStream(new FileOutputStream(file));
				bos.write(curSTEPGraph().getXml().getBytes());
	    		bos.close();				
	        	jTabbedPane.setTitleAt(jTabbedPane.getSelectedIndex(), 
	        			file.getName());
			} catch (FileNotFoundException e) {
				JOptionPane.showMessageDialog(this, "File not found");
			} catch (IOException e) {
				JOptionPane.showMessageDialog(this, "An I/O Error occured writing this file.  Do you have write privledges on the device?  Is it full?");
			} 
    	
        }
		status.setDefaultMessage();
	}

	public void doActionFileSaveAs(ActionEvent evt) {
		doActionFileSave(evt);
		
	}

	public void doActionFileSavePng(ActionEvent evt) {
		status.setMessage("Saving PNG Image...", StatusBar.MSG_OK);
		
		StepFileFilter filter = new StepFileFilter(StepFileFilter.FORMAT_PNG);
		fileChooser.setFileFilter(filter);
		
		int returnVal = fileChooser.showSaveDialog(this);
		File saveFile =  new File(fileChooser.getSelectedFile().getPath());
		
		while(StepFileFilter.getExtension(saveFile) == null || !(StepFileFilter.getExtension(saveFile).equalsIgnoreCase("png"))) 
		{
			if(returnVal == JFileChooser.APPROVE_OPTION) 
			{
				JOptionPane.showMessageDialog(this, "File name must end with .png");
				returnVal = fileChooser.showSaveDialog(this);
				saveFile =  new File(fileChooser.getSelectedFile().getPath());
			}
		}
				
		if(StepFileFilter.getExtension(saveFile) != null && StepFileFilter.getExtension(saveFile).equalsIgnoreCase("png")) {			
			jTabbedPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

			BufferedImage bi = curSTEPGraph().getImage();
			try {
				ImageIO.write(bi, "png", new File(fileChooser.getSelectedFile().getPath()));
			}
			catch (IOException e) {
				ErrorManager.LogError(e);
				JOptionPane.showMessageDialog(this, "Save as PNG failed.");
			}
			jTabbedPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}
		
		status.setDefaultMessage();
		
	}

	public void doActionImportOpcode(ActionEvent evt) {
		status.setMessage("For a future version", StatusBar.MSG_DEFAULT);
		JOptionPane.showMessageDialog(this, "In-editor addition of opcodes is slated for future versions.\nTo add opcodes now, please edit the opcodes.xml file manually.");
		status.setDefaultMessage();
	}
	
	public void doActionQuit(ActionEvent evt) {
		System.exit(0);
	}

	public void doActionValidate(ActionEvent evt) {
		status.setMessage("Validating...", StatusBar.MSG_DEFAULT);
		
		ArrayList<step.exceptions.STEPException> errors = curSTEPGraph().ValidateSTEP();
		String message = "";
		for (int i = 0; i < errors.size(); i++) {
			step.exceptions.STEPException exception = errors.get(i);
			message += exception.toString();
		}

		if (message.length() > 0) {
			message = "The following errors were found in the graph:\n\n"
					+ message;
		} else {
			message = "No errors were found in the graph.";
		}

		JOptionPane.showMessageDialog(this, message);	
	}

	public void doActionViewXml(ActionEvent evt) {
		refreshXML();
		
	}

	public void doActionViewZoomIn(ActionEvent evt) {
		curSTEPGraph().Zoom(+1);
		
	}

	public void doActionViewZoomOut(ActionEvent evt) {
		curSTEPGraph().Zoom(-1);
	}

	public void doActionSetArrowMode(boolean b) {
		if(b){
			SelectedJTreeOperation = "ARROW";
			status.alterDefaultMessage(StatusBar.DEFAULT_MSG_ARROW_BEGIN);	
		}
		else{
			SelectedJTreeOperation = "Opcode";
			status.alterDefaultMessage(StatusBar.DEFAULT_MSG_NODES);
		}
		
	}

	private void resetArrowMode(){
		nodeFrom = null;
		if(SelectedJTreeOperation.equals("ARROW")){
			status.alterDefaultMessage(StatusBar.DEFAULT_MSG_ARROW_BEGIN);
		}
	}
	
	public void EdgeDoubleClicked(FakeStepNode src, FakeStepNode dst, int x, int y) {
		resetArrowMode();
	}

	public void EdgeLeftClicked(FakeStepNode src, FakeStepNode dst, int x, int y) {
		resetArrowMode();
	}

	public void EdgeRightClicked(FakeStepNode src, FakeStepNode dst, int x, int y) {
		resetArrowMode();

		if (EdgePopup == null) {
			EdgePopup = new EdgeContextMenu();
		}
		EdgePopup.setEvent(src,dst);
		
		if (EdgePopup.isVisible())
			EdgePopup.setVisible(false);
		else {
			EdgePopup.setVisible(true);
			
			EdgePopup.show(curSTEPGraph(), x,y);
		}	}

	public void doActionViewLayout(ActionEvent evt) {
		//curSTEPGraph().LayoutGraph();
	}	

}